#include <iostream>
#include "qzeroimage.h"


QZeroImage::QZeroImage( QWidget *parent)
  : QGLWidget( parent)
{
  zoom_ = 1.0f;
  angle_ = 0.0f;
  manipmode_ = "NONE";
  fademode_ = "NONE";
  xtrans_ = 0.0f;
  ytrans_ = 0.0f;
  alpha_ = 1.0f;
  this->setMouseTracking(true);

  m_timer = new QTimer( this );
  connect( m_timer, SIGNAL(timeout()), this, SLOT(updateScene()) );
}

void QZeroImage::initializeGL()
{
  glEnable(GL_TEXTURE_2D);
  glShadeModel(GL_SMOOTH);

  glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
  glClearDepth(1.0f);

  glEnable(GL_DEPTH_TEST);
  glDepthFunc(GL_LEQUAL);

  glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

  QZeroTexture tex;
  tex.Load("example2.jpg");
  theLayer_.setTexture(tex);

  //set up the menu bar
  menuBar_.setType(QZeroMenuBarTypeVertical);
  QZeroIconProperties prop1("tim.bmp", "zoom in", false);
  QZeroIconProperties prop2("tim.bmp", "zoom out", false);
  QZeroIconProperties prop3("tim.bmp", "pan", true);
  QZeroIconProperties prop4("tim.bmp", "rotate left", false);
  QZeroIconProperties prop5("tim.bmp", "rotate right", false);
  QZeroIconProperties prop6("tim.bmp", "reset view", false);

  menuBar_.addIcon(prop1);
  menuBar_.addIcon(prop2);
  menuBar_.addIcon(prop3);
  menuBar_.addIcon(prop4);
  menuBar_.addIcon(prop5);
  menuBar_.addIcon(prop6);
  menuBar_.setAlpha(alpha_);

}

void QZeroImage::resizeGL( int width, int height )
{
  height = height?height:1;

  glViewport( 0, 0, (GLint)width, (GLint)height );

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(0,this->width(),0,this->height(),1,-100);	//Set up an ortho screen

}

void QZeroImage::paintGL()
{
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  theLayer_.draw(this->width(), this->height(), 0);
  menuBar_.draw(this->width(), this->height(), 0);

  glFlush();

}


void QZeroImage::keyPressEvent( QKeyEvent *e )
{

}

void QZeroImage::mouseMoveEvent( QMouseEvent * e)
{
  menuBar_.mouselocation(e->x(), this->height() - e->y());
  bool mouseInside = menuBar_.mouseInsideMenuBar(e->x(), this->height() - e->y());

  if (fademode_ == "NONE")
  {
    if (!mouseInside && !menuBar_.hidden())
    {
      fademode_ = "FADE OUT";
      m_timer->start(100);
    }
    else if (mouseInside && menuBar_.hidden())
    {
      fademode_ = "FADE IN";
      m_timer->start(100);
    }
  }
  updateGL();
}

void QZeroImage::mousePressEvent( QMouseEvent * e)
{
  menuBar_.press(e->x(), this->height() - e->y());
  std::string action = menuBar_.action(e->x(), this->height() - e->y());
  std::cout << action << std::endl;

  std::string oldManipMode = manipmode_;

  if (action == "zoom in")
  {
    zoom_ *= 2.0f;
  }
  else if (action == "zoom out")
  {
    zoom_ /= 2.0f;
  }
  else if (action == "rotate left")
  {
    angle_ += 20.0f;
    if (angle_ > 360.0f)
    {
      angle_ -= 360.0f;
    }
  }
  else if (action == "rotate right")
  {
    angle_ -= 20.0f;
    if (angle_ < 0.0f)
    {
      angle_ += 360.0f;
    }
  }
  else if (action == "pan")
  {
    manipmode_ = (manipmode_ == "NONE") ? manipmode_ = "PAN" : manipmode_ = "NONE";
  }
  else if (action == "reset view")
  {
    zoom_ = 1.0f;
    angle_ = 0.0f;
    xtrans_ = 0.0f;
    ytrans_ = 0.0f;
  }
  else
  {

  }

  if (oldManipMode == manipmode_)
  {
    handleManipulator(e);
  }
  setLayerProperties();

  updateGL();
}

void QZeroImage::handleManipulator( QMouseEvent * e)
{
  if (manipmode_ == "PAN")
  {
    float clickx = e->x() - xtrans_;
    float clicky = this->height() - e->y() - ytrans_;
    xtrans_ = this->width() / 2 - clickx;
    ytrans_ = this->height()/2 - clicky;
  }
}

void QZeroImage::mouseReleaseEvent( QMouseEvent * e)
{
  menuBar_.release(e->x(), this->height() - e->y());
  updateGL();
}

void QZeroImage::setLayerProperties()
{
  theLayer_.setAngle(angle_);
  theLayer_.setXtrans(xtrans_);
  theLayer_.setYtrans(ytrans_);
  theLayer_.setZoom(zoom_);
}

void QZeroImage::timeOutSlot()
{
  std::cout << "timer running" << std::endl;
}

void QZeroImage::updateScene()
{
  if (fademode_ == "FADE OUT")
  {
    alpha_ -= 0.2f;
    if (alpha_ < 0.0f)
    {
      alpha_ = 0.0f;
      m_timer->stop();
      std::cout << "timer stopped" << std::endl;
      menuBar_.setHidden(true);
      fademode_ = "NONE";
    }
    menuBar_.setAlpha(alpha_);
    std::cout << "alpha is: " <<  alpha_ << std::endl;
  }

  if (fademode_ == "FADE IN")
  {
    alpha_ += 0.2f;
    if (alpha_ > 1.0f)
    {
      alpha_ = 1.0f;
      m_timer->stop();
      std::cout << "timer stopped" << std::endl;
      menuBar_.setHidden(false);
      fademode_ = "NONE";
    }
    menuBar_.setAlpha(alpha_);
    std::cout << "alpha is: " <<  alpha_ << std::endl;
  }
  updateGL();
}
